package com.zj.easywebview

import android.content.Context
import android.net.Uri
import android.text.TextUtils
import android.util.Log
import android.webkit.WebView
import android.widget.Toast
import java.lang.Exception
import java.lang.reflect.Method
import java.util.HashMap

/**
 * @author: zhengjun
 * created: 2021/9/27
 * desc:
 */
object JsBridge {
    var jsMethods: MutableMap<String, MutableMap<String, Method>> = HashMap()
    /**
     * 把类中的方法注进来
     *
     * @param exposedName
     * @param cls
     */
    fun register(exposedName: String, cls: Class<*>) {
        if (jsMethods.containsKey(exposedName)) return
        val methodMap: MutableMap<String, Method> = HashMap()
        for (method in cls.declaredMethods) {
            val parameterTypes = method.parameterTypes
            if (parameterTypes.size == 4 && parameterTypes[0] == Context::class.java && parameterTypes[1] == WebView::class.java && parameterTypes[2] == String::class.java && parameterTypes[3] == BridgeCallback::class.java) {
                methodMap[method.name] = method
            }
        }
        jsMethods[exposedName] = methodMap
    }


    /**
     * Js调用Java方法
     *
     * @param context
     * @param webView
     * @param uriString
     * @throws Exception
     */
    fun callJava(context: Context, webView: WebView, uriString: String?) {
        Log.d("uriString", uriString!!)
        //uriString = " http://bridgeImpl/addAddress";
        //http://nativeJsImpl/openActivity?{clsPath:.ui.user.MyInviteRecordActivity}
        val uri = Uri.parse(uriString)
        val exposedName = uri.host //nativeJsImpl
        val port = uri.port
        val methodName = uri.encodedPath!!.replace("/", "") // openActivity
        var param = uri.encodedQuery //{clsPath:.ui.user.MyInviteRecordActivity}
        val encodedFragment = uri.encodedFragment
        if (!TextUtils.isEmpty(encodedFragment)) {
            param += "#$encodedFragment"
        }
        if (jsMethods.containsKey(exposedName)) {
            val methodMap: Map<String, Method> = jsMethods[exposedName]!!
            if (methodMap.containsKey(methodName)) {
                val method = methodMap[methodName]!!
                method.invoke(
                    method.declaringClass.newInstance(),
                    context,
                    webView,
                    param,
                    BridgeCallback(port, webView)
                )
            } else {
                // 新增了方法，老版本没有
                updatePls(context)
            }
        } else {
            // 新增了类，老版本没有
            updatePls(context)
        }
    }

    private fun updatePls(context: Context) {
        Toast.makeText(context.applicationContext, "请升级到最新版本后重试", Toast.LENGTH_SHORT).show()
    }

}
